package com.shuai.AI.ai_app.app;

import com.shuai.AI.ai_app.advisor.MyLoggerAdvisor;
import com.shuai.AI.ai_app.config.ChatClientConfig;
import com.shuai.AI.ai_app.rag.other.QueryRewriter;
import jakarta.annotation.Resource;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.rag.advisor.RetrievalAugmentationAdvisor;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

@Component
@Slf4j
public class LoveApp {

  public record LoveReport(String title, List<String> suggestions) {}

  @Resource private ChatClient dashScopeChatClient;

  // 应用 RAG 本地知识库问答
  @Resource private SimpleVectorStore loveAppSimpleVectorStore;

  @Resource private RetrievalAugmentationAdvisor localRetrievalAugmentationAdvisor;

  // 应用 RAG 检索增强服务（基于云知识库服务)
  @Resource private RetrievalAugmentationAdvisor cloudRetrievalAugmentationAdvisor;

  // 应用 RAG 检索增强服务（基于 PgVector 向量存储）
  @Resource private VectorStore pgVectorVectorStore;

  @Resource private QueryRewriter queryRewriter;


  @Resource private ToolCallback[] allTools;

  @Resource private ToolCallbackProvider toolCallbackProvider;


  /**
   * AI 基础对话（支持多轮对话记忆）
   *
   * @param message
   * @param chatId
   * @return
   */
  public String doChat(String message, String chatId) {
    ChatResponse chatResponse =
            dashScopeChatClient
                    .prompt()
                    .user(message)
                    .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
                    .call()
                    .chatResponse();
    String content = chatResponse.getResult().getOutput().getText();
//    log.info("content: {}", content);
    return content;
  }

  /**
   * AI 基础对话（支持多轮对话记忆，SSE 流式传输）
   *
   * @param message
   * @param chatId
   * @return
   */
  public Flux<String> doChatByStream(String message, String chatId) {
    return dashScopeChatClient
            .prompt()
            .user(message)
            // 添加工具能力
            .toolCallbacks(allTools)
            .toolCallbacks(toolCallbackProvider)
            // 应用 RAG 本地知识库问答
//            .advisors(localRetrievalAugmentationAdvisor)
            .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
            .stream()
            .content();
  }



  /**
   * AI 恋爱报告功能（实战结构化输出）
   *
   * @param message
   * @param chatId
   * @return
   */

  public LoveReport doChatWithReport(String message, String chatId) {
    LoveReport loveReport =
        dashScopeChatClient
            .prompt()
            .system(ChatClientConfig.SYSTEM_PROMPT + "每次对话后都要生成恋爱结果，标题为{用户名}的恋爱报告，内容为建议列表")
            .user(message)
            .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
            .call()
            .entity(LoveReport.class);
    log.info("loveReport: {}", loveReport);
    return loveReport;
  }

  /** AI 恋爱知识库问答功能 */
  /**
   * 和 RAG 知识库进行对话
   *
   * @param message
   * @param chatId
   * @return
   */
  public String doChatWithRag(String message, String chatId) {
    // 查询重写
    //    String reWriteMsg = queryRewriter.doQueryRewrite(message);
    ChatResponse chatResponse =
        dashScopeChatClient
            .prompt()
            //            .user(reWriteMsg)
            .user(message)
            .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
            // 应用 RAG 本地知识库问答
//            .advisors(new QuestionAnswerAdvisor(loveAppSimpleVectorStore))
                .advisors(localRetrievalAugmentationAdvisor)
            //            .advisors(new QuestionAnswerAdvisor(loveAppSimpleVectorStore))
            //             应用 RAG 检索增强服务（基于云知识库服务)
            //            .advisors(cloudRetrievalAugmentationAdvisor)
            // 应用 RAG 检索增强服务（基于 PgVector 向量存储）
            //                .advisors(new QuestionAnswerAdvisor(pgVectorVectorStore))
            // 应用自定义的 RAG 检索增强服务（文档查询器 + 上下文增强器）
            //                .advisors(
            //                        LoveAppRagCustomAdvisorFactory.createLoveAppRagCustomAdvisor(
            //                                loveAppVectorStore, "单身"
            //                        )
            //                )
            .call()
            .chatResponse();
    String content = chatResponse.getResult().getOutput().getText();
    //    log.info("content: {}", content);
    return content;
  }

  // AI 调用工具能力
  /**
   * AI 恋爱报告功能（支持调用工具）
   *
   * @param message
   * @param chatId
   * @return
   */
  public String doChatWithTools(String message, String chatId) {
    ChatResponse chatResponse =
            dashScopeChatClient
                    .prompt()
                    .user(message)
                    .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
                    // 开启日志，便于观察效果
                    .advisors(new MyLoggerAdvisor())
                    .toolCallbacks(allTools)
                    .call()
                    .chatResponse();
    String content = chatResponse.getResult().getOutput().getText();
//    log.info("content: {}", content);
    return content;
  }


//   AI 调用 MCP 服务
  /**
   * AI 恋爱报告功能（调用 MCP 服务）
   *
   * @param message
   * @param chatId
   * @return
   */
  public String doChatWithMcp(String message, String chatId) {
    ChatResponse chatResponse =
            dashScopeChatClient
                    .prompt()
                    .user(message)
                    .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
                    // 开启日志，便于观察效果
                    .advisors(new MyLoggerAdvisor())
                    .toolCallbacks(toolCallbackProvider)
                    .call()
                    .chatResponse();
    return chatResponse.getResult().getOutput().getText();
  }
}
